import chap3._
import org.scalatest.FunSuite

class Chap3Suit extends  FunSuite {
  test("practice 3.1") {
    val x = List(1, 2, 3, 4) match {
      case Cons(x, Cons(2, Cons(4, _))) => x
      case Nil => 42
      case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y
      case Cons(h,t) => h + List.sum(t)
      case _ => 102
    }
    assert(x == 3)
  }
  test("practice 3.2") {
    val x = List(1, 2, 3)
    assert(List.tail(x) == List(2, 3))
  }

  test("practice 3.3") {
    val x = List(1, 2, 3)
    assert(List.setHead(x, 2) == List(2, 2, 3))
  }

  test("practice 3.4") {
    val x = List(1, 2, 3)
    assert(List.drop(x, 1) == List(2, 3))
  }

  test("practice 3.5") {
    val x = List(1, 2, 3)
    assert(List.dropWhile(x)(x => x < 3) == List(3))
  }

  test("practice 3.6") {
    val x = List(1, 2, 3)
    val y = List.init(x)
    assert(List.init(x) == List(1, 2))
  }

  test("practice 3.9") {
    assert(List.length(List(1, 2, 3)) == 3)
  }

  test("practice 3.10") {
    assert(List.foldLeft(List(1, 2, 3), 0)(_ + _) == 6)
  }

  test("practice 3.11") {
    assert(List.sum2(List(1, 2, 3)) == 6)
    assert(List.product2(List(1, 2, 3)) == 6.0)
    assert(List.length2(List(1, 2, 3)) == 3)
  }

  test("practice 3.12") {
    assert(List.reverse(List(1, 2, 3)) == List(3, 2, 1))
  }

  test("practice 3.13") {
    assert(List.foldRight2(List(1, 2, 3), "")((a, b) =>  a.toString + b) == "123")
    assert(List.foldRight2(List(1, 2, 3), "")((a, b) =>  b + a.toString) == "321")
  }

  test("practice 3.14") {
    assert(List.append2(List(1, 2, 3), List(4, 5, 6)) == List(1, 2, 3, 4, 5, 6))
  }

  test("practice 3.15") {
    assert(List.join(List(1), List(2, 3), List(4, 5, 6)) == List(1, 2, 3, 4, 5, 6))
  }

  test("practice 3.16") {
    assert(List.inc(List(1, 2, 3)) == List(2, 3, 4))
  }

  test("practice 3.17") {
    assert(List.tostring(List(1.0, 2.0, 3.0)) == List("1.0", "2.0", "3.0"))
  }

  // practice 3.18 is just a map implementation

  test("practice 3.19") {
    assert(List.filterOdds(List(1, 2 ,3)) == List(2))
  }

  test("practice 3.20") {
    assert(List.flatMap(List(1, 2, 3))(a => List(a, a)) == List(1, 1, 2, 2, 3, 3))
  }

  test("practice 3.21") {
    assert(List.filter2(List(1, 2, 3))(_ > 2) == List(3))
  }

  test("practice 3.22") {
    assert(List.zipWith(List(1, 2, 3), List(1, 2, 3))(_ + _) == List(2, 4, 6))
  }

  test("practice 3.23") {
    assert(List.zip(List(1, 2, 3), List(1, 2, 3)) == List(2, 4, 6))
  }
}